#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import os
from typing import List, Optional
import argparse
from datetime import datetime
from prompt_manager import PromptManager
from models import PromptItem, Category


class PromptCLI:
    """提示词管理命令行界面"""
    
    def __init__(self, data_dir: str = "data"):
        self.manager = PromptManager(data_dir)
        self.data_dir = data_dir
    
    def print_header(self, title: str):
        """打印标题"""
        print("\n" + "=" * 60)
        print(f"  {title}")
        print("=" * 60)
    
    def print_prompt(self, prompt: PromptItem, show_content: bool = True):
        """打印提示词信息"""
        status = "✅" if prompt.enabled else "❌"
        category = self.manager.get_category_by_id(prompt.category_id)
        category_name = category.name if category else "未知分类"
        
        print(f"\n{status} [{prompt.id}] {prompt.title}")
        print(f"   分类: {category_name}")
        if prompt.tags:
            print(f"   标签: {', '.join(prompt.tags)}")
        if prompt.variables:
            print(f"   变量: {', '.join(prompt.variables)}")
        if show_content:
            print(f"   内容: {prompt.content[:100]}{'...' if len(prompt.content) > 100 else ''}")
    
    def print_category(self, category: Category):
        """打印分类信息"""
        status = "✅" if category.enabled else "❌"
        count = self.manager.get_prompt_count_by_category(category.id)
        print(f"{status} [{category.id}] {category.name} ({count}个提示词)")
        if category.description:
            print(f"   描述: {category.description}")
        if category.color:
            print(f"   颜色: {category.color}")
    
    def list_prompts(self, args):
        """列出提示词"""
        self.print_header("提示词列表")
        
        # 搜索提示词
        prompts = self.manager.search_prompts(
            query=args.query or "",
            category_id=args.category,
            tags=args.tags.split(',') if args.tags else None,
            enabled_only=args.enabled_only
        )
        
        if not prompts:
            print("未找到匹配的提示词")
            return
        
        print(f"找到 {len(prompts)} 个提示词:")
        for prompt in prompts:
            self.print_prompt(prompt, show_content=not args.brief)
    
    def add_prompt(self, args):
        """添加提示词"""
        self.print_header("添加提示词")
        
        # 交互式输入
        if not args.title:
            args.title = input("请输入标题: ").strip()
        if not args.content:
            print("请输入内容 (输入END结束):")
            content_lines = []
            while True:
                line = input()
                if line.strip() == "END":
                    break
                content_lines.append(line)
            args.content = "\n".join(content_lines)
        
        # 处理标签
        tags = []
        if args.tags:
            tags = [tag.strip() for tag in args.tags.split(',') if tag.strip()]
        elif not args.no_interactive:
            tag_input = input("请输入标签 (用逗号分隔，可选): ").strip()
            if tag_input:
                tags = [tag.strip() for tag in tag_input.split(',') if tag.strip()]
        
        # 选择分类
        category_id = args.category or "default"
        if not args.category and not args.no_interactive:
            categories = self.manager.get_all_categories()
            print("\n可用分类:")
            for i, cat in enumerate(categories):
                print(f"  {i+1}. {cat.name} ({cat.id})")
            
            try:
                choice = input(f"请选择分类 (1-{len(categories)}, 默认为1): ").strip()
                if choice and choice.isdigit():
                    idx = int(choice) - 1
                    if 0 <= idx < len(categories):
                        category_id = categories[idx].id
            except ValueError:
                pass
        
        # 添加提示词
        prompt = self.manager.add_prompt(
            title=args.title,
            content=args.content,
            tags=tags,
            category_id=category_id
        )
        
        if prompt:
            print(f"\n✅ 提示词添加成功!")
            self.print_prompt(prompt)
        else:
            print("❌ 提示词添加失败!")
    
    def edit_prompt(self, args):
        """编辑提示词"""
        self.print_header("编辑提示词")
        
        prompt = self.manager.get_prompt_by_id(args.id)
        if not prompt:
            print(f"❌ 未找到提示词: {args.id}")
            return
        
        print("当前提示词信息:")
        self.print_prompt(prompt)
        
        # 交互式编辑
        if not args.no_interactive:
            print("\n请输入新值 (直接回车保持不变):")
            
            new_title = input(f"标题 [{prompt.title}]: ").strip()
            if new_title:
                args.title = new_title
            
            print(f"当前内容: {prompt.content[:100]}{'...' if len(prompt.content) > 100 else ''}")
            edit_content = input("是否编辑内容? (y/N): ").strip().lower()
            if edit_content == 'y':
                print("请输入新内容 (输入END结束):")
                content_lines = []
                while True:
                    line = input()
                    if line.strip() == "END":
                        break
                    content_lines.append(line)
                args.content = "\n".join(content_lines)
            
            current_tags = ', '.join(prompt.tags) if prompt.tags else '无'
            new_tags = input(f"标签 [{current_tags}]: ").strip()
            if new_tags:
                args.tags = new_tags
        
        # 处理更新参数
        update_kwargs = {}
        if args.title:
            update_kwargs['title'] = args.title
        if args.content:
            update_kwargs['content'] = args.content
        if args.tags:
            update_kwargs['tags'] = [tag.strip() for tag in args.tags.split(',') if tag.strip()]
        if args.category:
            update_kwargs['category_id'] = args.category
        if args.enabled is not None:
            update_kwargs['enabled'] = args.enabled
        
        if update_kwargs:
            success = self.manager.update_prompt(args.id, **update_kwargs)
            if success:
                print("\n✅ 提示词更新成功!")
                updated_prompt = self.manager.get_prompt_by_id(args.id)
                if updated_prompt:
                    self.print_prompt(updated_prompt)
            else:
                print("❌ 提示词更新失败!")
        else:
            print("没有需要更新的内容")
    
    def delete_prompt(self, args):
        """删除提示词"""
        self.print_header("删除提示词")
        
        prompt = self.manager.get_prompt_by_id(args.id)
        if not prompt:
            print(f"❌ 未找到提示词: {args.id}")
            return
        
        print("要删除的提示词:")
        self.print_prompt(prompt)
        
        if not args.force:
            confirm = input("\n确认删除? (y/N): ").strip().lower()
            if confirm != 'y':
                print("取消删除")
                return
        
        success = self.manager.delete_prompt(args.id)
        if success:
            print("✅ 提示词删除成功!")
        else:
            print("❌ 提示词删除失败!")
    
    def list_categories(self, args):
        """列出分类"""
        self.print_header("分类列表")
        
        categories = self.manager.get_all_categories()
        if not categories:
            print("未找到分类")
            return
        
        print(f"共 {len(categories)} 个分类:")
        for category in categories:
            self.print_category(category)
    
    def add_category(self, args):
        """添加分类"""
        self.print_header("添加分类")
        
        if not args.name:
            args.name = input("请输入分类名称: ").strip()
        
        if not args.description and not args.no_interactive:
            args.description = input("请输入分类描述 (可选): ").strip() or None
        
        if not args.color and not args.no_interactive:
            args.color = input("请输入分类颜色 (如 #ff0000, 可选): ").strip() or None
        
        category = self.manager.add_category(
            name=args.name,
            description=args.description,
            color=args.color
        )
        
        if category:
            print("\n✅ 分类添加成功!")
            self.print_category(category)
        else:
            print("❌ 分类添加失败!")
    
    def delete_category(self, args):
        """删除分类"""
        self.print_header("删除分类")
        
        category = self.manager.get_category_by_id(args.id)
        if not category:
            print(f"❌ 未找到分类: {args.id}")
            return
        
        print("要删除的分类:")
        self.print_category(category)
        
        prompt_count = self.manager.get_prompt_count_by_category(args.id)
        if prompt_count > 0:
            print(f"\n⚠️  该分类下有 {prompt_count} 个提示词，删除后将移动到默认分类")
        
        if not args.force:
            confirm = input("\n确认删除? (y/N): ").strip().lower()
            if confirm != 'y':
                print("取消删除")
                return
        
        success = self.manager.delete_category(args.id)
        if success:
            print("✅ 分类删除成功!")
        else:
            print("❌ 分类删除失败!")
    
    def show_stats(self, args):
        """显示统计信息"""
        self.print_header("统计信息")
        
        stats = self.manager.get_statistics()
        
        print(f"📊 基本统计:")
        print(f"   总提示词数: {stats['total_prompts']}")
        print(f"   启用提示词: {stats['enabled_prompts']}")
        print(f"   禁用提示词: {stats['disabled_prompts']}")
        print(f"   总分类数: {stats['total_categories']}")
        print(f"   总标签数: {stats['total_tags']}")
        print(f"   总变量数: {stats['total_variables']}")
        
        if args.detailed:
            print(f"\n📁 分类统计:")
            for name, info in stats['category_stats'].items():
                status = "✅" if info['enabled'] else "❌"
                print(f"   {status} {name}: {info['count']} 个提示词")
            
            print(f"\n🏷️  热门标签:")
            sorted_tags = sorted(stats['tag_stats'].items(), key=lambda x: x[1], reverse=True)
            for tag, count in sorted_tags[:10]:  # 显示前10个
                print(f"   {tag}: {count} 次")
            
            if stats['variable_stats']:
                print(f"\n🔧 常用变量:")
                sorted_vars = sorted(stats['variable_stats'].items(), key=lambda x: x[1], reverse=True)
                for var, count in sorted_vars[:10]:  # 显示前10个
                    print(f"   {{{{var}}}}: {count} 次")
    
    def export_data(self, args):
        """导出数据"""
        self.print_header("导出数据")
        
        if not args.output:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            args.output = f"prompts_export_{timestamp}.json"
        
        success = self.manager.export_prompts(args.output)
        if success:
            print(f"✅ 数据导出成功: {args.output}")
        else:
            print(f"❌ 数据导出失败: {args.output}")
    
    def import_data(self, args):
        """导入数据"""
        self.print_header("导入数据")
        
        if not os.path.exists(args.input):
            print(f"❌ 文件不存在: {args.input}")
            return
        
        if not args.force:
            print(f"将从 {args.input} 导入数据")
            if args.merge:
                print("模式: 合并 (不会覆盖现有数据)")
            else:
                print("模式: 覆盖 (将替换所有现有数据)")
            
            confirm = input("\n确认导入? (y/N): ").strip().lower()
            if confirm != 'y':
                print("取消导入")
                return
        
        success = self.manager.import_prompts(args.input, merge=args.merge)
        if success:
            print("✅ 数据导入成功!")
            # 显示导入后的统计
            stats = self.manager.get_statistics()
            print(f"当前共有 {stats['total_prompts']} 个提示词，{stats['total_categories']} 个分类")
        else:
            print("❌ 数据导入失败!")
    
    def backup_data(self, args):
        """备份数据"""
        self.print_header("备份数据")
        
        backup_file = self.manager.backup_data(args.backup_dir)
        if backup_file:
            print(f"✅ 数据备份成功: {backup_file}")
        else:
            print("❌ 数据备份失败!")
    
    def search_prompts(self, args):
        """搜索提示词"""
        self.print_header(f"搜索结果: '{args.query}'")
        
        prompts = self.manager.search_prompts(
            query=args.query,
            category_id=args.category,
            tags=args.tags.split(',') if args.tags else None,
            enabled_only=args.enabled_only
        )
        
        if not prompts:
            print("未找到匹配的提示词")
            return
        
        print(f"找到 {len(prompts)} 个匹配的提示词:")
        for prompt in prompts:
            self.print_prompt(prompt, show_content=not args.brief)
    
    def use_prompt(self, args):
        """使用提示词（替换变量）"""
        self.print_header("使用提示词")
        
        prompt = self.manager.get_prompt_by_id(args.id)
        if not prompt:
            print(f"❌ 未找到提示词: {args.id}")
            return
        
        print("提示词信息:")
        self.print_prompt(prompt)
        
        if prompt.variables:
            print(f"\n🔧 需要填入变量: {', '.join(prompt.variables)}")
            
            variable_values = {}
            for var in prompt.variables:
                value = input(f"请输入 '{var}' 的值: ").strip()
                variable_values[var] = value
            
            result = prompt.replace_variables(variable_values)
            print("\n📝 最终内容:")
            print("-" * 40)
            print(result)
            print("-" * 40)
        else:
            print("\n📝 提示词内容:")
            print("-" * 40)
            print(prompt.content)
            print("-" * 40)


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description="提示词管理工具")
    parser.add_argument('--data-dir', default='data', help='数据存储目录')
    
    subparsers = parser.add_subparsers(dest='command', help='可用命令')
    
    # 列出提示词
    list_parser = subparsers.add_parser('list', help='列出提示词')
    list_parser.add_argument('--query', help='搜索关键词')
    list_parser.add_argument('--category', help='分类ID')
    list_parser.add_argument('--tags', help='标签 (用逗号分隔)')
    list_parser.add_argument('--enabled-only', action='store_true', help='只显示启用的提示词')
    list_parser.add_argument('--brief', action='store_true', help='简要显示')
    
    # 添加提示词
    add_parser = subparsers.add_parser('add', help='添加提示词')
    add_parser.add_argument('--title', help='标题')
    add_parser.add_argument('--content', help='内容')
    add_parser.add_argument('--tags', help='标签 (用逗号分隔)')
    add_parser.add_argument('--category', help='分类ID')
    add_parser.add_argument('--no-interactive', action='store_true', help='非交互模式')
    
    # 编辑提示词
    edit_parser = subparsers.add_parser('edit', help='编辑提示词')
    edit_parser.add_argument('id', help='提示词ID')
    edit_parser.add_argument('--title', help='新标题')
    edit_parser.add_argument('--content', help='新内容')
    edit_parser.add_argument('--tags', help='新标签 (用逗号分隔)')
    edit_parser.add_argument('--category', help='新分类ID')
    edit_parser.add_argument('--enabled', type=bool, help='启用状态')
    edit_parser.add_argument('--no-interactive', action='store_true', help='非交互模式')
    
    # 删除提示词
    delete_parser = subparsers.add_parser('delete', help='删除提示词')
    delete_parser.add_argument('id', help='提示词ID')
    delete_parser.add_argument('--force', action='store_true', help='强制删除，不确认')
    
    # 分类管理
    cat_list_parser = subparsers.add_parser('categories', help='列出分类')
    
    cat_add_parser = subparsers.add_parser('add-category', help='添加分类')
    cat_add_parser.add_argument('--name', help='分类名称')
    cat_add_parser.add_argument('--description', help='分类描述')
    cat_add_parser.add_argument('--color', help='分类颜色')
    cat_add_parser.add_argument('--no-interactive', action='store_true', help='非交互模式')
    
    cat_delete_parser = subparsers.add_parser('delete-category', help='删除分类')
    cat_delete_parser.add_argument('id', help='分类ID')
    cat_delete_parser.add_argument('--force', action='store_true', help='强制删除，不确认')
    
    # 统计信息
    stats_parser = subparsers.add_parser('stats', help='显示统计信息')
    stats_parser.add_argument('--detailed', action='store_true', help='显示详细统计')
    
    # 导入导出
    export_parser = subparsers.add_parser('export', help='导出数据')
    export_parser.add_argument('--output', help='输出文件路径')
    
    import_parser = subparsers.add_parser('import', help='导入数据')
    import_parser.add_argument('input', help='输入文件路径')
    import_parser.add_argument('--merge', action='store_true', default=True, help='合并模式 (默认)')
    import_parser.add_argument('--overwrite', action='store_true', help='覆盖模式')
    import_parser.add_argument('--force', action='store_true', help='强制导入，不确认')
    
    backup_parser = subparsers.add_parser('backup', help='备份数据')
    backup_parser.add_argument('--backup-dir', default='backups', help='备份目录')
    
    # 搜索
    search_parser = subparsers.add_parser('search', help='搜索提示词')
    search_parser.add_argument('query', help='搜索关键词')
    search_parser.add_argument('--category', help='分类ID')
    search_parser.add_argument('--tags', help='标签 (用逗号分隔)')
    search_parser.add_argument('--enabled-only', action='store_true', help='只搜索启用的提示词')
    search_parser.add_argument('--brief', action='store_true', help='简要显示')
    
    # 使用提示词
    use_parser = subparsers.add_parser('use', help='使用提示词')
    use_parser.add_argument('id', help='提示词ID')
    
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        return
    
    # 处理导入参数
    if args.command == 'import' and args.overwrite:
        args.merge = False
    
    # 创建CLI实例
    cli = PromptCLI(args.data_dir)
    
    # 执行命令
    command_map = {
        'list': cli.list_prompts,
        'add': cli.add_prompt,
        'edit': cli.edit_prompt,
        'delete': cli.delete_prompt,
        'categories': cli.list_categories,
        'add-category': cli.add_category,
        'delete-category': cli.delete_category,
        'stats': cli.show_stats,
        'export': cli.export_data,
        'import': cli.import_data,
        'backup': cli.backup_data,
        'search': cli.search_prompts,
        'use': cli.use_prompt
    }
    
    if args.command in command_map:
        try:
            command_map[args.command](args)
        except KeyboardInterrupt:
            print("\n\n操作已取消")
        except Exception as e:
            print(f"\n❌ 执行命令时出错: {e}")
            if '--debug' in sys.argv:
                import traceback
                traceback.print_exc()
    else:
        print(f"未知命令: {args.command}")
        parser.print_help()


if __name__ == '__main__':
    main()